package com.sfj.common.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.ZipUtil;
import com.sfj.common.exception.BizException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * @author kaka
 * @Date 2025/5/1
 */
public class FileImportExport {

    private static final String DOLLOR = "$";
    private static final String ZIP = ".zip";

    public static File getFile(String fileJson, String fileName) {
        return FileUtil.writeBytes(fileJson.getBytes(StandardCharsets.UTF_8), fileName);
    }

    public static File getFile(String fileJson, File file) {
        return FileUtil.writeBytes(fileJson.getBytes(StandardCharsets.UTF_8), file);
    }


    public static InputStream copyAndzip(List<File> fileList, File fileDir) {
        fileList.forEach(it -> {
            FileUtil.copy(it, fileDir, true);
        });
        return export(fileDir);
    }

    //无代码应用打包使用
    public static InputStream copyAndzip(List<File> fileList, List<File> jarFile, File fileDir) {
        fileList.forEach(it -> {
            FileUtil.copy(it, fileDir, true);
        });
        if (CollUtil.isNotEmpty(jarFile)) {
            jarFile.forEach(file -> {
                FileUtil.copy(file, fileDir, true);
            });
        }
        return export(fileDir);
    }

    public static void delFile(File path) {
        try {
            FileUtil.del(path);
        } catch (IORuntimeException e) {
            throw new BizException("[BIZ] 导出应用信息失败!", e);
        }
    }

    public static InputStream export(File fileDir) {

        String zipFilePath = fileDir.getName() + ZIP;
        File zipFile = ZipUtil.zip(fileDir.getPath(), zipFilePath, true);
        try {
            InputStream inputStream = new FileInputStream(zipFile);
            return inputStream;
        } catch (FileNotFoundException e) {
            throw new BizException("[BIZ] 导出应用信息失败!", e);
        }
    }

    //解压zip文件里的所有文件
    public static List<byte[]> extractZipContents(InputStream zipInputStream) throws IOException {
        List<byte[]> contents = new ArrayList<>();

        try (ZipInputStream zipIn = new ZipInputStream(zipInputStream)) {
            ZipEntry entry;
            while ((entry = zipIn.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    byte[] entryContent = IOUtils.toByteArray(zipIn);
                    contents.add(entryContent);
                }
                zipIn.closeEntry();
            }
        }

        return contents;
    }

    public static List<LinkedHashMap<String, Object>> transformDynamicData(List<LinkedHashMap<String, Object>> rawData) {
        List<LinkedHashMap<String, Object>> transformedData = new ArrayList<>();
        LinkedHashMap<String, LinkedHashMap<String, Object>> groupedData = new LinkedHashMap<>();

        for (Map<String, Object> row : rawData) {
            // 1. 确定分组键
            String key = row.getOrDefault("输入框", "") + "_" + row.getOrDefault("字段3", "");

            if (!groupedData.containsKey(key)) {
                // 2. 初始化新数据对象
                LinkedHashMap<String, Object> newData = new LinkedHashMap<>();
                for (String field : row.keySet()) {
                    if (!field.contains(".")) { // 只复制非嵌套字段
                        newData.put(field, row.get(field));
                    }
                }
                // 3. 动态初始化所有的表格 JSON 数组
                Set<String> tablePrefixes = getAllTablePrefixes(row);
                for (String prefix : tablePrefixes) {
                    newData.put(prefix, new ArrayList<>()); // 设为空列表
                }
                groupedData.put(key, newData);
            }

            // 4. 归类表格字段到 JSON 数组
            Map<String, Object> currentData = groupedData.get(key);
            Set<String> tablePrefixes = getAllTablePrefixes(row);

            for (String prefix : tablePrefixes) {
                List<Map<String, Object>> tableList = (List<Map<String, Object>>) currentData.get(prefix);
                Map<String, Object> tableEntry = new LinkedHashMap<>();

                for (String field : row.keySet()) {
                    if (field.startsWith(prefix + ".")) {
                        //空字符串默认为null
                        if (!StringUtils.isEmpty((CharSequence) row.get(field))) {
                            tableEntry.put(field.replace(prefix + ".", ""), row.get(field));
                        }
                    }
                }
                if (!tableEntry.isEmpty()) {
                    tableList.add(tableEntry);
                }
            }
        }

        transformedData.addAll(groupedData.values());
        return transformedData;
    }

    /**
     * 获取所有表格前缀，比如 ["表格", "表格2"]
     */
    private static Set<String> getAllTablePrefixes(Map<String, Object> row) {
        Set<String> prefixes = new HashSet<>();
        for (String field : row.keySet()) {
            int dotIndex = field.indexOf(".");
            if (dotIndex > 0) {
                prefixes.add(field.substring(0, dotIndex)); // 提取前缀
            }
        }
        return prefixes;
    }
}
